<?php

namespace app\astrologer\controller\v2;

use app\astrologer\controller\AstrAuth;
use app\astrologer\controller\Upload;
use app\common\cachemodel\AppConfig;
use app\common\cachemodel\ZlcrAstr;
use app\common\cachemodel\ZlcrAstrAccount;
use app\common\cachemodel\ZlcrAstrExercise;
use app\common\cachemodel\ZlcrAstrExerciseRecord;
use app\common\cachemodel\ZlcrAstrInfo;
use app\common\cachemodel\ZlcrAstrMessage;
use app\common\cachemodel\ZlcrContentCheck;
use app\common\lib\Util;
use think\Cache;
use think\Db;
use think\Env;
use think\exception\DbException;
use think\Log;
use think\response\Json;

/**
 * Class User
 * 占星师用户信息
 * @package app\astrologer\controller\v2
 */
class User extends AstrAuth
{
    /**
     * 每关 每一题 分数
     * @var array
     */
    private $questionScore = [
        1 => 10,
        2 => 20,
    ];

    /**
     * 每关 通关 分数【总分】
     * @var array
     */
    private $levelSuccessScore = [
        1 => [  // 定制报告
            1 => 350,// 答对35题第一关考试通过(ps:每题10分)
            2 => 0,
        ],
        2 => [  // 三合一问答考试
            1 => 500,// 答对54题第一关考试通过(ps:每题10分)
            2 => 0,
        ],
        3 => [  // 问答-星盘
            1 => 250,// 答对27题第一关考试通过(ps:每题10分)
            2 => 0,
        ],
        4 => [  // 问答-骰子
            1 => 250,// 答对27题第一关考试通过(ps:每题10分)
            2 => 0,
        ],
        5 => [  // 问答-塔罗
            1 => 250,// 答对27题第一关考试通过(ps:每题10分)
            2 => 0,
        ],
    ];

    /**
     * 获取当前用户信息
     */
    public function info()
    {
        $host = Env::get('host.photo');

        $roles = ['astrologer_not_completed'];//未完成章程学习的角色
        if ((int)$this->astrInfo['check_status'] === 40)
        {
            $roles = ['astrologer'];//完成章程学习的角色/特邀用户
        }
        $accountInfo = (new ZlcrAstrAccount())->getAstrAccountInfo($this->astrInfo['id'], ['balance']);
        $authStatus = $this->astrInfo['auth_status'];
        $passList = [
            0 => $authStatus['custom_report'],
            1 => $authStatus['question_answer_astr'],
            2 => $authStatus['question_answer_dice'],
            3 => $authStatus['question_answer_tarot'],
        ];

        $pauseTime = $this->astrInfo['pause_time'] - time();

        $data = [
            'avatar' => $this->astrInfo['avatar'] ? $host . $this->astrInfo['avatar'] : '',
            'introduction' => 'I am a super administrator',
            'name' => $this->astrInfo['nickname'],
            'astr_level' => (int)$this->astrInfo['astr_level'],
            'astro_grade' => (int)$this->astrInfo['astro_grade'],
            'status' => (int)$this->astrInfo['status'], // 1=>正常 0=>禁止（禁止登陆） 2=>账号冻结（可以登录，但是不能接单）长期冻结
            'step' => \app\astrologer\controller\User::$statusInfo[$this->astrInfo['check_status']],// 0=>未开始,1=>注册成功,2=>占星考试完成,3=>完善资料完成,4=>平台培训完成,5=>,100为已通过全部占星师接单要求
            'roles' => $roles,//'astrologer_not_completed':未完成章程学习的角色;'astrologer':完成章程学习的角色/特邀用户
            'percent_proportion' => $this->astrInfo['proportion'] * 100,  // 收益比例百分比
            'percent_rate' => (int)$this->astrInfo['rating'],  // 好评率百分比
            'create_date' => date('Y-m-d', $this->astrInfo['create_time']), //账号创建日期
            'tel' => substr_replace($this->astrInfo['tel'], '****', 3, 4),//手机号
            'hint' => Util::getAstrologerLevelUpDes((int)$this->astrInfo['astr_level'], (int)$this->astrInfo['astro_grade']),//升级提示
            'earns' => $accountInfo['balance'],
            'pause_status' => $pauseTime > 0 ? 1 : 0, // 账户临时冻结状态 到时间自动解冻 1=>账号冻结 0=>未冻结
            'pause_time' => $pauseTime > 0 ? $pauseTime : 0, // 距离解冻剩余时间的 时间戳
            'is_have_new_msg' => (new ZlcrAstrMessage())->getNewMessageNum($this->astrInfo['id']) > 0 ? 1 : 0,//是否显示消息new图标：1=》显示；0=》不显示
            'pass_list' => $passList
        ];
        return show(200, '请求成功', $data);
    }

    /**
     * 获取考试状态
     */
    public function getAssessmentData()
    {
        $imgHost = Env::get('host.photo');
        $type = input('type/d', 0); // 0=>注册场景 1=>个人中心认证 2=>问答相关认证 3=>定制报告相关认证

        $astrInfo = (new ZlcrAstrInfo())->getInfoById($this->astrInfo['id'], 'id');
        $data = [
            'msg_title' => $type === 1 ? '' : '恭喜您注册成功',
            'msg_des' => $type === 1 ? '' : '恭喜您成功注册占星平台，完成以下流程后即可正式入驻占星平台',
            'list' => [],
            'is_complete_info' => $astrInfo ? 1 : 0
        ];
        $is_pass_all = true;//是否通过了所有考试

        $authStatus = $this->astrInfo['auth_status'];
        $astrAnswerModel = new ZlcrAstrExerciseRecord();
        if (in_array($type, [0, 1, 2], true))
        {
            if ($authStatus['question_answer_astr'] === 0 || $this->astrInfo['check_status'] < 30)
            {   // 获取用户当前答题状态信息
                $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], 3);   // 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
                $res = $astrAnswerModel->getExerciseRes2($astrAnswerInfo);

                $questionAnswerAstrStatus = $res[1]['status'];  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                $questionAnswerAstrTips = $res[1]['tips'];
                $questionAnswerAstr2Status = $res[2]['status'];  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                $questionAnswerAstr2Tips = $res[2]['tips'];
                $is_pass_all = false;
            }
            if ($authStatus['question_answer_dice'] === 0 || $this->astrInfo['check_status'] < 30)
            {   // 获取用户当前答题状态信息
                $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], 4);   // 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
                $res = $astrAnswerModel->getExerciseRes2($astrAnswerInfo);

                $questionAnswerDiceStatus = $res[1]['status'];  // 考试状态
                $questionAnswerDiceTips = $res[1]['tips'];  //
                $questionAnswerDice2Status = $res[2]['status'];  // 考试状态
                $questionAnswerDice2Tips = $res[2]['tips'];  //
                $is_pass_all = false;
            }
            if ($authStatus['question_answer_tarot'] === 0 || $this->astrInfo['check_status'] < 30)
            {   // 获取用户当前答题状态信息
                $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], 5);   // 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
                $res = $astrAnswerModel->getExerciseRes2($astrAnswerInfo);
                $questionAnswerTarotStatus = $res[1]['status']; // 考试状态
                $questionAnswerTarotTips = $res[1]['tips']; //
                $questionAnswerTarot2Status = $res[2]['status']; // 考试状态
                $questionAnswerTarot2Tips = $res[2]['tips']; //
                $is_pass_all = false;
            }

            $questionAnswerMergeIsPassed = $authStatus['question_answer_astr'] === 1 && $authStatus['question_answer_dice'] === 1 && $authStatus['question_answer_tarot'] === 1 ? 1 : 0;
            if ($questionAnswerMergeIsPassed === 0 || $this->astrInfo['check_status'] < 30)
            {
                $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], 2);   // 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
                $res = $astrAnswerModel->getExerciseRes2($astrAnswerInfo);
                $questionAnswerMergeStatus = $res[1]['status']; // 考试状态
                $questionAnswerMergeTips = $res[1]['tips']; //
                $questionAnswerMerge2Status = $res[2]['status']; // 考试状态
                $questionAnswerMerge2Tips = $res[2]['tips']; //
            }

            $data['list'][] = [
                'title' => '问答技能考核',
                'list' => [
                    [
                        'type' => 2,
                        'img' => $imgHost . '/mini/astrologer/test/1.png',
                        'name' => '3合1综合技能测试',
                        'desc' => '您需要熟练掌握星盘、占星骰子、塔罗的相关知识，能独立输出自己的观点。',
                        'tips' => $questionAnswerMergeIsPassed && $this->astrInfo['check_status'] >= 30 ? '已获得所有问答的接单资格' : '通过后可获得所有问答的接单资格',
                        'is_passed' => $questionAnswerMergeIsPassed && $this->astrInfo['check_status'] >= 30 ? 1 : 0,
                        'list' => [
                            [
                                'id' => 1,
                                'title' => '选择题',
                                'status' => $questionAnswerMergeStatus ?? 2,  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerMergeTips ?? '',
                                'content' => [
                                    '每个人每类测评每天只有1次测评机会，未通过则24小时后重试。',
                                    '考试限时60分钟内完成，如果测试中途退出，结果保留，可继续进行测试。',
                                    '共60道题，答对50道题通过考试，每道题限时1分钟内完成，超时自动判错，通过后即可申请基础面试考核。',
                                ],
                            ], [
                                'id' => 3,
                                'title' => '基础面试',
                                'status' => $questionAnswerMerge2Status ?? 2,  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerMerge2Tips ?? '',
                                'content' => [],
                            ]
                        ],
                    ],
                    [
                        'type' => 3,
                        'img' => $imgHost . '/mini/astrologer/test/2.png',
                        'name' => '咨询师测评-星盘问答',
                        'desc' => '您需要熟练掌握星盘相关知识，能独立输出自己的观点。',
                        'tips' => $authStatus['question_answer_astr'] === 1 && $this->astrInfo['check_status'] >= 30 ? '已获得星盘问答的接单资格' : '通过后可获得星盘问答的接单资格',
                        'is_passed' => $authStatus['question_answer_astr'] === 1 && $this->astrInfo['check_status'] >= 30 ? 1 : 0 ? 1 : 0,
                        'list' => [
                            [
                                'id' => 1,
                                'title' => '选择题',
                                'status' => $questionAnswerAstrStatus ?? 2, // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerAstrTips ?? '',
                                'content' => [
                                    '每个人每类测评每天只有1次测评机会，未通过则24小时后重试。',
                                    '考试限时40分钟内完成，如果测试中途退出，结果保留，可继续进行测试。',
                                    '共30道题，答对25道题通过考试，每道题限时1分钟内完成，超时自动判错，通过后即可申请基础面试考核。',
                                ],
                            ], [
                                'id' => 3,
                                'title' => '基础面试',
                                'status' => $questionAnswerAstr2Status ?? 2,  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerAstr2Tips ?? '',
                                'content' => [],
                            ]
                        ],
                    ],
                    [
                        'type' => 4,
                        'img' => $imgHost . '/mini/astrologer/test/3.png',
                        'name' => '咨询师测评-骰子问答',
                        'desc' => '您需要熟练掌握占星骰子相关知识，能独立输出自己的观点。',
                        'tips' => $authStatus['question_answer_dice'] === 1 && $this->astrInfo['check_status'] >= 30 ? '已获得骰子问答的接单资格' : '通过后可获得骰子问答的接单资格',
                        'is_passed' => $authStatus['question_answer_dice'] === 1 && $this->astrInfo['check_status'] >= 30 ? 1 : 0 ? 1 : 0,
                        'list' => [
                            [
                                'id' => 1,
                                'title' => '选择题',
                                'status' => $questionAnswerDiceStatus ?? 2,// 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerDiceTips ?? '',
                                'content' => [
                                    '每个人每类测评每天只有1次测评机会，未通过则24小时后重试。',
                                    '考试限时40分钟内完成，如果测试中途退出，结果保留，可继续进行测试。',
                                    '共30道题，答对25道题通过考试，每道题限时1分钟内完成，超时自动判错，通过后即可申请基础面试考核。',
                                ],
                            ], [
                                'id' => 3,
                                'title' => '基础面试',
                                'status' => $questionAnswerDice2Status ?? 2,  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerDice2Tips ?? '',
                                'content' => [],
                            ]
                        ],
                    ],
                    [
                        'type' => 5,
                        'img' => $imgHost . '/mini/astrologer/test/4.png',
                        'name' => '咨询师测评-塔罗问答',
                        'desc' => '您需要熟练掌握塔罗相关知识，能独立输出自己的观点。',
                        'tips' => $authStatus['question_answer_tarot'] === 1 && $this->astrInfo['check_status'] >= 30 ? '已获得塔罗问答的接单资格' : '通过后可获得塔罗问答的接单资格',
                        'is_passed' => $authStatus['question_answer_tarot'] === 1 && $this->astrInfo['check_status'] >= 30 ? 1 : 0 ? 1 : 0,
                        'list' => [
                            [
                                'id' => 1,
                                'title' => '选择题',
                                'status' => $questionAnswerTarotStatus ?? 2,// 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerTarotTips ?? '',
                                'content' => [
                                    '每个人每类测评每天只有1次测评机会，未通过则24小时后重试。',
                                    '考试限时40分钟内完成，如果测试中途退出，结果保留，可继续进行测试。',
                                    '共30道题，答对25道题通过考试，每道题限时1分钟内完成，超时自动判错，通过后即可申请基础面试考核。',
                                ],
                            ], [
                                'id' => 3,
                                'title' => '基础面试',
                                'status' => $questionAnswerTarot2Status ?? 2,  // 考试状态 // -1=>不可以考试（前端不可点击）、0=>可以考试（前端可以点击）、1=>未通过、2=>已通过、3=》审核中
                                'tips' => $questionAnswerTarot2Tips ?? '',
                                'content' => [],
                            ]
                        ],
                    ],
                ]
            ];
        }

        if (in_array($type, [0, 1, 3], true))
        {
            if ($authStatus['custom_report'] === 0 || $this->astrInfo['check_status'] < 30)
            {   // 获取用户当前答题状态信息
                $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], 1);   // 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗

                $res = $astrAnswerModel->getExerciseRes2($astrAnswerInfo);
                $customReport1Status = $res[1]['status']; // 考试状态
                $customReport1Tips = $res[1]['tips']; //
                $customReport2Status = $res[2]['status']; // 考试状态
                $customReport2Tips = $res[2]['tips']; //
                $is_pass_all = false;
            }

            $data['list'][] = [
                'title' => '定制报告技能测试考核',
                'list' => [
                    [
                        'type' => 1,
                        'img' => $imgHost . '/mini/astrologer/test/5.png',
                        'name' => '占星师测评-定制报告',
                        'desc' => '您需要熟练掌握星盘相关知识，能独立输出自己的观点。',
                        'tips' => $authStatus['custom_report'] === 1 && $this->astrInfo['check_status'] >= 30 ? '已获得定制报告及星盘问答接单资格' : '通过后获得定制报告及星盘问答接单资格',
                        'is_passed' => $authStatus['custom_report'] === 1 && $this->astrInfo['check_status'] >= 30 ? 1 : 0 ? 1 : 0,
                        'list' => [
                            [
                                'id' => 1,
                                'title' => '选择题',
                                'status' => $customReport1Status ?? 2,
                                'tips' => $customReport1Tips ?? '',
                                'content' => [
                                    '选择题考核共40题，分单选及多选，答对35题则考核成功进入基础面试考核',
                                    '选择题考核每题回答时间为60秒，若超时则当前题默认0分，自动进入下一道题',
                                    '选择题考核总时长为1小时，若超过规定时间未提交则所有超时的题，自动设置为0分',
                                    '考核如不通过则从考试结束时间开始计算间隔24小时才可继续重新考核'
                                ],
                            ],
                            // [
                            //     'id' => 2,
                            //     'title' => '简答题',
                            //     'status' => $customReport2Status ?? 2,
                            //     'tips' => $customReport2Tips ?? '',
                            //     'content' => [
                            //         '占星师开始笔试考核后需要在特定星盘下回答指定问题，回复字数以及占星技法不限',
                            //         '笔试考核总计时间为4小时，点击开始笔试考核后开始计时。若超过指定时间未提交则自动设置为0分',
                            //         '提交回复后请占星师耐心等待，官方审核人员快马加鞭将在7个工作日内给予短信回复通知，请留意手机短信',
                            //         '通过笔试考核后则可继续登录填写资料完成后续入驻流程'
                            //     ],
                            // ],
                            [
                                'id' => 3,
                                'title' => '基础面试',
                                'status' => $customReport2Status ?? 2,
                                'tips' => $customReport2Tips ?? '',
                                'content' => [],
                            ],
                        ],
                    ],
                ],
            ];
        }

        if ($type === 1)
        {//个人中心点击认证考试
            if ($is_pass_all)
            {//已通过全部考试
                $data['msg_title'] = '';
                $data['msg_des'] = '';
            } else
            {//未通过全部考试，顶部的提示
                $data['msg_title'] = '你还有未通过的考核测试';
                $data['msg_des'] = '你可以选择一下考核测试，获得相应的接单资格';
            }
        }

        return show(200, '请求成功', $data);
    }

    /**
     * 获取考试题目
     * @throws Exception
     */
    public function getExamineQuestion()
    {
        $type = input('type/d', 0); // 考试类型 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
        $index = input('index/d', 0);
        $option = trim(input('option/s', ''));

        if (!in_array($type, [1, 2, 3, 4, 5], true))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }

        if ($type === 1 && $this->astrInfo['auth_status']['custom_report'] === 1)
        {
            return show(config('code.error'), '定制报告占星师测评已经通过了');
        }
        if ($type === 2 && $this->astrInfo['auth_status']['question_answer_astr'] === 1 && $this->astrInfo['auth_status']['question_answer_dice'] === 1 && $this->astrInfo['auth_status']['question_answer_tarot'] === 1)
        {
            return show(config('code.error'), '3合1综合技能测评已经通过了');
        }
        if ($type === 3 && $this->astrInfo['auth_status']['question_answer_astr'] === 1)
        {
            return show(config('code.error'), '星盘问答咨询师测评已经通过了');
        }
        if ($type === 4 && $this->astrInfo['auth_status']['question_answer_dice'] === 1)
        {
            return show(config('code.error'), '骰子问答咨询师测评已经通过了');
        }
        if ($type === 5 && $this->astrInfo['auth_status']['question_answer_tarot'] === 1)
        {
            return show(config('code.error'), '塔罗问答咨询师测评已经通过了');
        }

        $questionModel = new ZlcrAstrExercise();
        $astrAnswerModel = new ZlcrAstrExerciseRecord();

        // 获取用户当前答题状态信息
        $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], $type);

        if (Env::get('host.name') !== 'online')
        {
            $this->levelSuccessScore[$type] = [
                1 => 10,
                2 => 0,
            ];
        }

        if ($astrAnswerInfo)
        {
            $astrAnswerInfo['status'] = (int)$astrAnswerInfo['status'];
        }
        if ($astrAnswerInfo && $astrAnswerInfo['status'] === 2)
        {
            if ((int)$astrAnswerInfo['level'] === 1 && $this->request->time() - $astrAnswerInfo['fail_time'] > 86400)
            {
                $astrAnswerInfo = null; // 失败24小时后重新考试
                $astrAnswerModel->rmCacheData($this->astrInfo['id'], $type);
            } else if ((int)$astrAnswerInfo['level'] === 2 && $astrAnswerInfo['content2'])
            {
                $content2 = \GuzzleHttp\json_decode($astrAnswerInfo['content2'], true);
                if ($this->request->time() - $astrAnswerInfo['fail_time'] > 86400 * ($content2['interview']['agian_days'] ?? 0))
                {
                    $astrAnswerInfo = null; // 失败后重新考试
                    $astrAnswerModel->rmCacheData($this->astrInfo['id'], $type);
                } else
                {
                    return show(config('code.error'), '当前考核已结束');
                }
            } else
            {
                return show(config('code.error'), '当前考核已结束');
            }
        }
        // 获取当前用户答题进度
        if (!$astrAnswerInfo)
        {   // 初始化答题进度
            switch ($type)
            {
                case 1:
                    // 获取第一关 随机35题
                    $num_option_one = 35;   // 单选题目数
                    $num_option_mul = 5;    // 多选题目数
                    if (Env::get('host.name') !== 'online')
                    {
                        $num_option_one = 1;
                        $num_option_mul = 5;
                    }
                    $questionIds = $questionModel->randomGetQuestionId(1, $num_option_one, 1);
                    shuffle($questionIds);
                    $Level2QuestionIds = $questionModel->randomGetQuestionId(2, $num_option_mul, 1);
                    shuffle($Level2QuestionIds);
                    $questionIds = array_merge($questionIds, $Level2QuestionIds);

                    $questionNum = $num_option_one + $num_option_mul; // 总题目数
                    break;
                case 2:
                    $question1Ids = $questionModel->randomGetQuestionId(1, 20, 3);
                    $question2Ids = $questionModel->randomGetQuestionId(1, 20, 4);
                    $question3Ids = $questionModel->randomGetQuestionId(1, 20, 5);
                    $questionIds = array_merge($question1Ids, $question2Ids, $question3Ids);
                    shuffle($questionIds);
                    $questionNum = 60; // 总题目数
                    break;
                default:    // 3=>问答星盘 4=>问答骰子 5=>问答塔罗  考试题目数为30题
                    $questionNum = 30;
                    $questionIds = $questionModel->randomGetQuestionId(1, $questionNum, $type);
            }
            if (!$questionIds)
            {
                return show(config('code.error'), '服务异常；请稍后再试～');
            }

            $content1 = [
                'question' => $questionIds,
                'start_time' => $this->request->time(), // 开始答题时间
                'index' => 1, // 当前第几题
                'max_question' => $questionNum,  // 总题目数
                'max_answer_time' => 60, // 最大答题时长
                'answer' => [] // 答案信息
            ];

            $cacheData = [
                'create_time' => $this->request->time(),
                'astr_id' => $this->astrInfo['id'],
                'content1' => \GuzzleHttp\json_encode($content1, JSON_UNESCAPED_UNICODE),
                'type' => $type,
                'content2' => '',
                'content3' => '',
                'content4' => '',
                'grade1' => 0,
                'grade2' => 0,
                'grade3' => 0,
                'grade4' => 0,
                'grade' => 0,
                'level' => 1,
                'status' => 1,
                'answer_time' => 0, //答题耗时 总时长
                'fail_time' => 0, // 失败时间
            ];

            $astrAnswerModel->setCacheData($cacheData, $this->astrInfo['id'], $type);

            $questionId = $questionIds[$content1['index'] - 1];// 获取当前题目ID

            $resData = $this->getResultData($content1, $questionId, 10);
        } else
            switch ($astrAnswerInfo['level'])
            {
                case 1:
                    // 提交答案 ｜ 获取题目 ｜ 结果
                    $content1 = \GuzzleHttp\json_decode($astrAnswerInfo['content1'], true);
                    if ($astrAnswerInfo['status'] === 2 || (isset($content1['answer_total_time']) && $content1['answer_total_time']))
                    {
                        $resData = [
                            'step' => 11,
                            'answer_right' => $content1['answer_right_num'],
                            'answer_wrong' => $content1['answer_wrong_num'],
                            'timeout_num' => $content1['answer_timeout_num'],
                            'max_question' => $content1['max_question'],
                            'isSuccessful' => false, // 是否通关
                            'tips' => '很遗憾您未能通过考核，请24小时后再次尝试'
                        ];
                        break;
                    }
                    if ($index && $option && $index <= $content1['index'])
                    {   // 提交答案
                        $res = $this->nextQuestion($content1, $index, $option, 10);
                        if ($res['updateCache'])
                        {   // 是否更新缓存
                            $astrAnswerInfo['content1'] = \GuzzleHttp\json_encode($res['content'], JSON_UNESCAPED_UNICODE);
                            if ($res['isOver'])
                            {
                                $score = $res['content']['answer_right_num'] * $this->questionScore[1];//每题5分
                                $astrAnswerInfo['grade1'] = $score; // 第一关分数
                                $astrAnswerInfo['grade'] += $score; // 总分数
                                $astrAnswerInfo['answer_time'] += $res['content']['answer_total_time']; // 答题总时长
                                if ($astrAnswerInfo['grade1'] < $this->levelSuccessScore[$type][1]) // 总分
                                {   // 通关失败
                                    $astrAnswerInfo['status'] = 2;//挑战结束
                                    $astrAnswerInfo['fail_time'] = $this->request->time();
                                } else
                                {
                                    $astrAnswerInfo['level']++; // 升级下一关
                                }
                                unset($astrAnswerInfo['id']);

                                $id = $astrAnswerModel->insertGetId($astrAnswerInfo);

                                $astrAnswerInfo['id'] = $id;

                                $tips = $astrAnswerInfo['status'] === 2 ? '很遗憾您未能通过考核，请24小时后再次尝试' : '恭喜你通过选择题测试，继续完成面试即可通过考核。';

                                $resData = [
                                    'step' => 11,
                                    'answer_right' => $res['content']['answer_right_num'],
                                    'answer_wrong' => $res['content']['answer_wrong_num'],
                                    'timeout_num' => $res['content']['answer_timeout_num'],
                                    'max_question' => $res['content']['max_question'],
                                    'isSuccessful' => $astrAnswerInfo['status'] !== 2, // 是否通关
                                    'tips' => $tips
                                ];
                                $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存
                                //发送钉钉通知
                                Util::sendZlcrMsg(7, ['占星师ID：' . $this->astrInfo['id'], '总计:' . $resData['max_question'] . ',答对:' . $resData['answer_right'] . ',答错:' . $resData['answer_wrong']], $this->headers['app-type']);
                                break;
                            }

                            $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存
                        }
                        $resData = $res['resData'];
                    } else
                    {   // 获取题目
                        $isNext = ($this->request->time() - $content1['start_time']) >= $content1['max_answer_time']; // 是否下一题
                        if ($isNext)
                        {   // 下一题
                            $res = $this->nextQuestion($content1, $content1['index'], '', 10);
                            if ($res['updateCache'])
                            {   // 是否更新缓存
                                $astrAnswerInfo['content1'] = \GuzzleHttp\json_encode($res['content'], JSON_UNESCAPED_UNICODE);
                                if ($res['isOver'])
                                {
                                    $score = $res['content']['answer_right_num'] * $this->questionScore[1];//每题5分
                                    $astrAnswerInfo['grade1'] = $score; // 第一关分数
                                    $astrAnswerInfo['grade'] += $score; // 总分数
                                    $astrAnswerInfo['answer_time'] += $res['content']['answer_total_time']; // 答题总时长

                                    if ($astrAnswerInfo['grade1'] < $this->levelSuccessScore[$type][1]) // 总分
                                    {   // 通关失败
                                        $astrAnswerInfo['status'] = 2;//挑战结束
                                        $astrAnswerInfo['fail_time'] = $this->request->time();
                                    } else
                                    {
                                        $astrAnswerInfo['level']++; // 升级下一关
                                    }
                                    unset($astrAnswerInfo['id']);

                                    $id = $astrAnswerModel->insertGetId($astrAnswerInfo);

                                    $astrAnswerInfo['id'] = $id;

                                    $tips = $astrAnswerInfo['status'] === 2 ? '很遗憾您未能通过考核，请24小时后再次尝试' : '恭喜你通过选择题测试，继续完成面试即可通过考核。';

                                    $resData = [
                                        'step' => 11,
                                        'answer_right' => $res['content']['answer_right_num'],
                                        'answer_wrong' => $res['content']['answer_wrong_num'],
                                        'timeout_num' => $res['content']['answer_timeout_num'],
                                        'max_question' => $res['content']['max_question'],
                                        'isSuccessful' => $astrAnswerInfo['status'] !== 2, // 是否通关
                                        'tips' => $tips
                                    ];
                                    $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存
                                    //发送钉钉通知
                                    Util::sendZlcrMsg(7, ['占星师ID：' . $this->astrInfo['id'], '总计:' . $resData['max_question'] . ',答对:' . $resData['answer_right'] . ',答错:' . $resData['answer_wrong']], $this->headers['app-type']);
                                    break;
                                }

                                $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存
                            }
                            $resData = $res['resData'];
                        } else
                        {   // 当前题
                            $resData = $this->getResultData($content1, $content1['question'][$content1['index'] - 1], 10);
                        }
                    }
                    break;
                case 2:
                    if ($astrAnswerInfo['content2'])
                    {
                        $content2 = \GuzzleHttp\json_decode($astrAnswerInfo['content2'], true);
                        if ($content2['answer'])
                        {   // 提交过答案了
                            $resData = [
                                'step' => 21,
                                "index" => 1,//当前为第几题
                                "max_question" => 1,//总共有多少题
                                "tips" => '等待审核'
                            ];
                            break;
                        }
                        if ($option)
                        {   // 回答问题
                            $answerTime = $this->request->time() - $content2['start_time'];// 答题时间

                            if ($answerTime > ($content2['max_answer_time'] + 100))
                            { // 超时100秒提交 则无效
                                $option = '';
                            }
                            $content2['answer'] = [
                                'answer_time' => $answerTime > $content2['max_answer_time'] ? $content2['max_answer_time'] : $answerTime,
                                'option' => $option,
                                'start_time' => date('Y-m-d H:i:s', $content2['start_time']),
                            ];
                            $astrAnswerInfo['content2'] = \GuzzleHttp\json_encode($content2, JSON_UNESCAPED_UNICODE);
                            $astrAnswerInfo['answer_time'] += $content2['answer']['answer_time'];
                            $astrAnswerInfo['status'] = $option ? 4 : 2;  // 4=>待审核 ｜ 2=>失败
                            $astrAnswerInfo['fail_time'] = $content2['start_time'] + $content2['max_answer_time'];
                            // 更新
                            $astrAnswerModel->where('id', $astrAnswerInfo['id'])->update([
                                'update_time' => $this->request->time(),
                                'content2' => $astrAnswerInfo['content2'],
                                'answer_time' => $astrAnswerInfo['answer_time'],
                                'fail_time' => $astrAnswerInfo['fail_time'],
                                'status' => $astrAnswerInfo['status'],
                                'level' => $astrAnswerInfo['level']
                            ]);

                            if ($astrAnswerInfo['status'] === 4)
                            {
                                if ($this->astrInfo['check_status'] < 20)
                                {
                                    (new ZlcrAstr())->UpdateData($this->astrInfo['id'], ['id' => $this->astrInfo['id']], ['check_status' => 11]);
                                }
                            }

                            $resData = [
                                'step' => 21,
                                "index" => 1,//当前为第几题
                                "max_question" => 1,//总共有多少题
                                "tips" => $astrAnswerInfo['status'] === 2 ? '很遗憾您未能通过考核，请24小时后再次尝试' : '等待审核'
                            ];

                            $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存

                            //发送钉钉通知
                            Util::sendZlcrMsg(1, ['请尽快审核'], $this->headers['app-type']);
                            break;
                        }

                        // 获取问题
                        $isNext = ($this->request->time() - $content2['start_time']) >= $content2['max_answer_time']; // 是否下一题
                        if ($isNext)
                        {
                            $content2['answer'] = [
                                'answer_time' => $content2['max_answer_time'],
                                'option' => '',
                                'start_time' => date('Y-m-d H:i:s', $content2['start_time']),
                            ];
                            $astrAnswerInfo['content2'] = \GuzzleHttp\json_encode($content2, JSON_UNESCAPED_UNICODE);
                            $astrAnswerInfo['answer_time'] += $content2['max_answer_time'];
                            $astrAnswerInfo['status'] = 2;
                            $astrAnswerInfo['fail_time'] = $content2['start_time'] + $content2['max_answer_time'];
                            // 更新
                            $astrAnswerModel->where('id', $astrAnswerInfo['id'])->update([
                                'update_time' => $this->request->time(),
                                'content2' => $astrAnswerInfo['content2'],
                                'answer_time' => $astrAnswerInfo['answer_time'],
                                'fail_time' => $astrAnswerInfo['fail_time'],
                                'status' => $astrAnswerInfo['status'],
                                'level' => $astrAnswerInfo['level']
                            ]);
                            $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存

                            $resData = [
                                'step' => 21,
                                "index" => 1,//当前为第几题
                                "max_question" => 1,//总共有多少题
                                "tips" => '很遗憾您未能通过考核，请24小时后再次尝试'
                            ];
                            break;
                        }
                        $resData = $this->getResultData($content2, $content2['question'][$content2['index'] - 1], 20);
                    } else
                    {
                        if ($astrAnswerInfo['status'] === 2 || $astrAnswerInfo['grade1'] < $this->levelSuccessScore[$type][1]) // 当前关卡分数满足条件
                        {
                            return show(config('code.error'), '当前考核已结束');
                        }
                        // 初始化第二关答题进度
                        // 获取第二关 随机1题
                        $questionIds = $questionModel->randomGetQuestionId(3, 1, 1);

                        if (!$questionIds)
                        {
                            return show(config('code.error'), '服务异常；请稍后再试～');
                        }

                        $content2 = [
                            'question' => $questionIds,
                            'start_time' => $this->request->time(), // 开始答题时间
                            'index' => 1, // 当前第几题
                            'max_question' => 1,  // 总题目数
                            'max_answer_time' => 14400, // 最大答题时长 4小时
                            'answer' => [] // 答案信息
                        ];
                        $questionId = $questionIds[$content2['index'] - 1];// 获取当前题目ID

                        $astrAnswerInfo['content2'] = \GuzzleHttp\json_encode($content2, JSON_UNESCAPED_UNICODE);
                        $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存

                        $resData = $this->getResultData($content2, $questionId, 20);
                    }
                    break;
                default:
                    return show(config('code.error'), '服务异常；请稍后再试～');
            }

        // 返回结果
        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 返回题目信息
     * @param $content array 问题信息
     * @param $qid int  问题ID
     * @param $step int 当前进度 10=>第一关进行中 20=>第二关进行中 30=>第三关进行中 40=>第四关进行中
     * @return array
     * @throws Exception
     */
    private function getResultData(array $content, int $qid, int $step): array
    {
        $questionInfo = (new ZlcrAstrExercise())->getInfoById($qid, ['title', 'option_a', 'option_b', 'option_c', 'option_d', 'title_img', 'option_type']);

        $endTime = $content['max_answer_time'] ? $content['max_answer_time'] - ($this->request->time() - $content['start_time']) : 0;
        $tips = '';
        if ((int)$questionInfo['option_type'] === 3)
        {
//            $times = $this->request->time() + $endTime;
//            $tips = date('Y.m.d H:i:s', $times);
            $tips = '等待审核';
            $astro = [
                'is_merage' => false,
                'id' => $qid
            ];
        } else
        {
            $topicOption = [
                [
                    'text' => htmlspecialchars_decode($questionInfo['option_a']),
                    'value' => 'A'
                ],
                [
                    'text' => htmlspecialchars_decode($questionInfo['option_b']),
                    'value' => 'B'
                ],
                [
                    'text' => htmlspecialchars_decode($questionInfo['option_c']),
                    'value' => 'C'
                ],
                [
                    'text' => htmlspecialchars_decode($questionInfo['option_d']),
                    'value' => 'D'
                ]
            ];
        }

        return [
            'step' => $step,
            'index' => (int)$content['index'],
            'max_question' => (int)$content['max_question'],
            'end_time' => $endTime,
            'title' => htmlspecialchars_decode($questionInfo['title']),
            'topic_option' => $topicOption ?? null,
            'astro' => $astro ?? null,
            'option_type' => (int)$questionInfo['option_type'],
            'title_img' => $questionInfo['title_img'] ? Env::get('host.photo') . $questionInfo['title_img'] : '',
            'tips' => $tips
        ];
    }

    /**
     * 提交答案 进入下一题 ｜ 计算结果
     * @param $content array 关卡内容
     * @param $index int  当前题目
     * @param $option string 答案
     * @param $setp int 当前进度 10=>第一关进行中 20=>第二关进行中 30=>第三关进行中 40=>第四关进行中
     * @return array
     * @throws Exception
     */
    private function nextQuestion(array $content, int $index, string $option, int $setp): array
    {
        if ($index < $content['index'])
        {  // 可能情况  网络异常或其他 回答上一题答案
            $updateCache = false;
            if ($index === ($content['index'] - 1) && (($answerTime = $this->request->time() - strtotime($content['answer'][$index]['start_time'])) < ($content['max_answer_time'] + 10)))
            { // 在上一题允许范围内 则 为有效答题
                $content['answer'][$index] = [
                    'answer_time' => $answerTime > $content['max_answer_time'] ? $content['max_answer_time'] : $answerTime, // 当前问题消耗时长
                    'option' => $option, // 答案
                    'start_time' => $content['answer'][$index]['start_time']
                ];
            } else
            { // 无效答题
                if ($content['max_answer_time'] > 0 && ($this->request->time() - $content['start_time']) >= $content['max_answer_time'])
                { // 当前答案回答时间 也过期
                    $content['answer'][$content['index']] = [
                        'answer_time' => $content['max_answer_time'], // 当前问题消耗时长
                        'option' => '', // 答案
                        'start_time' => date('Y-m-d H:i:s', $content['start_time'])
                    ];
                    $content['index']++;
                    $updateCache = true;
                    if ($content['index'] > $content['max_question'])
                    { // 计算结果 | 返回答题信息
                        // 计算答题信息
                        $content = $this->totalScore($content);
                        return [
                            'content' => $content,
                            'updateCache' => true,
                            'isOver' => true,
                        ];
                    }
                    $content['start_time'] = $this->request->time();
                }
            }

            return [
                'content' => $content,
                'updateCache' => $updateCache,
                'isOver' => false,
                'resData' => $this->getResultData($content, $content['question'][$content['index'] - 1], $setp)
            ];
        }

        // 正常提交答案
        $answerTime = $this->request->time() - $content['start_time'];
        if ($content['max_answer_time'] > 0 && (!$option || ($answerTime > ($content['max_answer_time'] + 10))))
        {   // 无效答题
            $option = '';
        }
        $content['answer'][$index] = [
            'answer_time' => $answerTime > $content['max_answer_time'] ? $content['max_answer_time'] : $answerTime, // 当前问题消耗时长
            'option' => $option, // 答案
            'start_time' => date('Y-m-d H:i:s', $content['start_time'])
        ];

        if ($content['index'] >= $content['max_question'])
        { // 计算结果 得分
            // 计算答题信息
            $content = $this->totalScore($content);
            return [
                'content' => $content,
                'updateCache' => true,
                'isOver' => true,
            ];
        }

        // 返回下一题
        $content['index']++;
        $content['start_time'] = $this->request->time();
        return [
            'content' => $content,
            'updateCache' => true,
            'isOver' => false,
            'resData' => $this->getResultData($content, $content['question'][$content['index'] - 1], $setp)
        ];
    }

    /**
     * 计算正确结果
     * @param $content
     * @return array
     * @throws Exception
     */
    private function totalScore(array $content): array
    {
        $questionInfo = (new ZlcrAstrExercise())->batchGetInfoByIds($content['question'], ['answer', 'option_type']);

        $answerTotalTime = 0; // 答题总时长
        $answerRight = 0;// 正确答题数
        $timeOutNum = 0;// 超时数量
        $answerWrong = 0;// 错误答题数
        $answerRightQuestion = [];// 回答正确的题目 第几题 题目从1开始
        for ($i = 1; $i <= $content['max_question']; $i++)
        {
            if (isset($content['answer'][$i]) && $content['answer'][$i]['option'])
            {   // 如果当前题目回答了
                // 判断是否正确
                if ($questionInfo[$content['question'][$i - 1]]['option_type'] == 1)
                {
                    $answer = strtoupper($content['answer'][$i]['option']);
                    $questionAnswer = strtoupper(trim($questionInfo[$content['question'][$i - 1]]['answer'])); // 问题答案
                } else
                {
                    $answer = explode(',', strtoupper($content['answer'][$i]['option'])); // 答案
                    $questionAnswer = explode(',', strtoupper(trim($questionInfo[$content['question'][$i - 1]]['answer']))); // 问题答案
                    asort($answer);
                    asort($questionAnswer);
                    $answer = array_values($answer);
                    $questionAnswer = array_values($questionAnswer);
                }
                if ($answer === $questionAnswer)
                {
                    $answerRight++;
                    $answerRightQuestion[] = $i;// 当前第几题回答正确
                } else
                {
                    $answerWrong++;
                }
                $answerTotalTime += $content['answer'][$i]['answer_time'];//答题时长
            } else
            {   // 当前题目超时未回答
                $timeOutNum++;
                $answerTotalTime += $content['max_answer_time']; // 答题时长
            }
        }

        $content['answer_total_time'] = $answerTotalTime; // 答题总时长
        $content['answer_right_num'] = $answerRight;    // 答对的题目数量
        $content['answer_timeout_num'] = $timeOutNum;    // 超时数量
        $content['answer_wrong_num'] = $answerWrong;    // 错误答题数
        $content['answer_right_question'] = $answerRightQuestion; // 答对的题目

        return $content;
    }

    /**
     * 获取面试状态信息
     */
    public function getInterviewData()
    {
        $type = input('type/d', 0); // 考试类型 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
        if (!in_array($type, [1, 2, 3, 4, 5], true))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }

        $host = Env::get('host.photo');
        $typeName = [
            1 => '定制报告面试',
            2 => '3合1面试',
            3 => '问答星盘面试',
            4 => '问答骰子面试',
            5 => '问答塔罗面试',
        ];

        $typeName2 = [
            1 => '定制报告基础面试',
            2 => '问答-3合1基础面试',
            3 => '问答-星盘基础面试',
            4 => '问答-骰子基础面试',
            5 => '问答-塔罗基础面试',
        ];
        $astrAnswerModel = new ZlcrAstrExerciseRecord();
        // $content2['interview'] = [
        //     'status' => 0,  // 面试申请状态  0未申请 1=>已申请 2=>面试中 3=>面试未通过  4=>面试已通过
        //     'interview_id' => 0, // 面试ID
        //     'agian_days' => 0,// 下次面试天数
        // ];
        // 获取用户当前答题状态信息
        $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], $type);

        if ($astrAnswerInfo && (int)$astrAnswerInfo['level'] === 2)
        {
            $astrInfo = (new ZlcrAstrInfo())->getInfoById($this->astrInfo['id'], ['id', 'name']);

            if (!$astrInfo)
            {
                return show(config('code.error'), '请完善信息后再试～');
            }

            $nickname = Util::decryptWithOpenssl($astrInfo['name']);

            $des = "{$typeName[$type]}+{$this->astrInfo['tel']}+{$nickname}";

            $astrAnswerInfo['status'] = (int)$astrAnswerInfo['status'];
            $appConfig = (new AppConfig())->configInfo('question_answer');
            if ($astrAnswerInfo['status'] === 2)
            {
                return show(config('code.success'), '请求成功', [
                    'status' => 3,
                    'icon' => $host . '/zhunle_astrologer/interview_over.png',
                    'title' => "非常遗憾\r\n你未通过{$typeName2[$type]}",
                    'des' => '',
                    'img_qr_url' => '',
                    'list' => [],
                    'btn_title' => '面试未通过',
                ]);
            }

            $content2 = $astrAnswerInfo['content2'] ? json_decode($astrAnswerInfo['content2'], true) : null;
            $interviewStatus = $content2 && isset($content2['interview']['status']) ? (int)$content2['interview']['status'] : 0;
            switch ($interviewStatus)
            {
                case 1: // 已申请
                    return show(config('code.success'), '请求成功', [
                        'status' => 1,
                        'icon' => $host . '/zhunle_astrologer/interviewing.png',
                        'title' => "已成功申请{$typeName2[$type]}\r\n请和官方保持联系",
                        'des' => '请截图添加官方微信，添加时请备注二维码下方信息，添加成功后，申请视频面试，面试过程3-5分钟。视频面试通过后，即可继续入驻咨询师平台。视频面试未通过需重新进行选择题测试，才可再次申请面试。',
                        'img_qr_url' => $appConfig['img_qr_url'],
                        'list' => [
                            [
                                'title' => '备注信息：',
                                'des' => $des,
                                'type' => 1,
                                'title_color' => '#8A8C98',
                                'des_color' => '#FFB500',
                            ]
                        ],
                        'btn_title' => '已申请面试，请耐心等待',
                    ]);
                    break;
                case 2: // 面试中
                    return show(config('code.success'), '请求成功', [
                        'status' => 5,
                        'icon' => $host . '/zhunle_astrologer/interviewing.png',
                        'title' => "已成功申请{$typeName2[$type]}\r\n请和官方保持联系",
                        'des' => '请截图添加官方微信，添加时请备注二维码下方信息，添加成功后，申请视频面试，面试过程3-5分钟。视频面试通过后，即可继续入驻咨询师平台。视频面试未通过需重新进行选择题测试，才可再次申请面试。',
                        'img_qr_url' => $appConfig['img_qr_url'],
                        'list' => [
                            [
                                'title' => '备注信息：',
                                'des' => $des,
                                'type' => 1,
                                'title_color' => '#8A8C98',
                                'des_color' => '#FFB500',
                            ]
                        ],
                        'btn_title' => '面试中',
                    ]);
                    break;
                case 3: // 面试未通过
                    return show(config('code.success'), '请求成功', [
                        'status' => 3,
                        'icon' => $host . '/zhunle_astrologer/interview_success.png',
                        'title' => "非常遗憾\r\n你未通过{$typeName2[$type]}",
                        'des' => '',
                        'img_qr_url' => '',
                        'list' => [],
                        'btn_title' => '面试未通过',
                    ]);
                    break;
                case 4: // 面试已通过
                    return show(config('code.success'), '请求成功', [
                        'status' => 2,  // 0=》未申请面试；1=>已申请面试；2=》面试已通过；3=》面试未通过；5=〉面试中
                        'icon' => $host . '/zhunle_astrologer/interview_over.png',
                        'title' => "恭喜你通过\r\n{$typeName2[$type]}",
                        'des' => '',
                        'img_qr_url' => '',
                        'list' => [],
                        'btn_title' => '面试已通过',
                    ]);
                    break;
                default:
                    return show(config('code.success'), '请求成功', [
                        'status' => 0,
                        'icon' => $host . '/zhunle_astrologer/request_interview.png',
                        'title' => "请添加微信联系官方\r\n完成{$typeName2[$type]}",
                        'des' => '请截图添加官方微信，添加时请备注二维码下方信息，添加成功后，申请视频面试，面试过程3-5分钟。视频面试通过后，即可继续入驻咨询师平台。视频面试未通过需重新进行选择题测试，才可再次申请面试。',
                        'img_qr_url' => $appConfig['img_qr_url'],
                        'list' => [
                            [
                                'title' => '备注信息：',
                                'des' => $des,
                                'type' => 1,
                                'title_color' => '#8A8C98',
                                'des_color' => '#FFB500',
                            ]
                        ],
                        'btn_title' => '已添加微信，申请面试',
                    ]);
            }
        } else
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }
    }

    /**
     * 申请/取消面试申请
     */
    public function operateInterview()
    {
        $type = input('type/d', 0); // 考试类型 1=>定制报告 2=>问答三合一 3=>问答星盘 4=>问答骰子 5=>问答塔罗
        $isCancle = input('is_cancle/d', 0); // 是否取消 申请
        if (!in_array($type, [1, 2, 3, 4, 5], true))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        $astrAnswerModel = new ZlcrAstrExerciseRecord();
        // 获取用户当前答题状态信息
        $astrAnswerInfo = $astrAnswerModel->getExerciseInfo($this->astrInfo['id'], $type);

        if ($astrAnswerInfo && in_array($astrAnswerInfo['status'], [1, 3], false))
        {
            $astrInfo = (new ZlcrAstrInfo())->getInfoById($this->astrInfo['id'], ['id']);
            if (!$astrInfo)
            {
                return show(config('code.error'), '请求完善信息后在来操作');
            }

            $content2 = $astrAnswerInfo['content2'] ? json_decode($astrAnswerInfo['content2'], true) : [];
            // $content2['interview'] = [
            //     'status' => 0,  // 面试申请状态  0未申请 1=>已申请 2=>面试中 3=>面试未通过  4=>面试已通过
            //     'interview_id' => 0, // 面试ID
            //     'agian_days' => 0,// 下次面试天数
            // ];
            $status = isset($content2['interview']['status']) ? (int)$content2['interview']['status'] : 0;
            if ($status === 1)
            {   // 取消面试
                if ($isCancle === 0)
                {   // 申请成功
                    return show(config('code.success'), '操作成功', [
                        'btn_title' => '已申请面试，请耐心等待',
                        'status' => 1
                    ]);
                }
                Db::table('wechat_backup_07_18_14_43_00.zlcr_astr_interview')->where('id', $content2['interview']['interview_id'])->update(['status' => 4]);    // 0=>申请面试  1=>面试中  2=>面试已通过 3=>面试未通过 4=>取消面试
                $content2['interview']['status'] = 0;   // 未申请
                $content2['interview']['interview_id'] = 0;
                $astrAnswerInfo['content2'] = json_encode($content2, JSON_UNESCAPED_UNICODE);

                // 更新
                $astrAnswerModel->where('id', $astrAnswerInfo['id'])->update([
                    'update_time' => $this->request->time(),
                    'content2' => $astrAnswerInfo['content2'],
                ]);

                $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存

                return show(config('code.success'), '操作成功', [
                    'btn_title' => '已添加微信，申请面试',
                    'status' => 0
                ]);
            } elseif ($status === 0)
            {   // 申请面试
                if ($isCancle === 1)
                {   // 取消成功
                    return show(config('code.success'), '操作成功', [
                        'btn_title' => '已添加微信，申请面试',
                        'status' => 0
                    ]);
                }
                $id = Db::table('wechat_backup_07_18_14_43_00.zlcr_astr_interview')->insertGetId([
                    'status' => 0,
                    'type' => $type,
                    'astr_id' => $this->astrInfo['id'],
                    'exam_id' => $astrAnswerInfo['id'],
                    'create_time' => $this->request->time()
                ]);
                $content2['interview']['status'] = 1;   // 已申请
                $content2['interview']['interview_id'] = $id;
                $astrAnswerInfo['content2'] = json_encode($content2, JSON_UNESCAPED_UNICODE);

                // 更新
                $astrAnswerModel->where('id', $astrAnswerInfo['id'])->update([
                    'update_time' => $this->request->time(),
                    'content2' => $astrAnswerInfo['content2'],
                ]);

                $astrAnswerModel->setCacheData($astrAnswerInfo, $this->astrInfo['id'], $type); // 更新缓存

                return show(config('code.success'), '操作成功', [
                    'btn_title' => '已申请面试，请耐心等待',
                    'status' => 1
                ]);
            } elseif ($status === 2)
            {
                return show(config('code.error'), '面试中，操作失败');
            } else
            {
                return show(config('code.error'), '状态异常，请返回重试');
            }

        } else
        {
            return show(config('code.error'), '服务异常，请稍后再试');
        }
    }

    /**
     * 用户完善资料
     * @return Json
     * @throws Exception
     */
    public function compoleteInfo()
    {
        $data['userinfo'] = $param = $this->request->param();

        //todo 校验信息
//back: "/upload/check/right/20210311/9a2fe81e71ea00fde00a83a6cc6086be.jpg"
//bank_branch_code: "308100005078"
//bank_name: "招商银行"
//bank_num: "6214850115717628"
//bank_user_id_number: "130984199009063611"
//bank_username: "李柏楠"
//bank_verfiy: "842750"
//face: "/upload/check/left/20210311/ee0d85fda4aff46408e8c311df330ae0.jpg"
//holding: "/upload/check/pic/20210311/a8f39e44c2b8717f3bb8845e10c71419.jpg"
//id_number: "130984199009063611"
//nickname: "李老师"
//tel: "18502127689"
//truename: "李柏楠"

        //astro认证状态 10=>占星师考核  11=>待审核  12=>考核未通过 20=>资料填写 21=>资料待审核 22=>资料审核未通过 30=>培训   40=>认证完成（可接单）
        $zlAstrModel = new ZlcrAstr();
        $zlAstrInfoModel = new ZlcrAstrInfo();
        $astrInfo = $zlAstrInfoModel->getInfoById($this->astrInfo['id']);
        if ($this->request->isPost())
        {
            //新增占星师身份信息
            $paramRes = $this->checkCompoleteInfoParam($param, $zlAstrModel);
            if ($paramRes['status'] === false)
            {
                return show(0, $paramRes['msg'], $paramRes['data']);
            }
            //支行名称替换
            if ($param['bank_name'] === '上海浦东发展银行')
            {
                $param['bank_name'] = '浦发银行';
            }
            if ($param['bank_name'] === '中国工商银行')
            {
                $param['bank_name'] = '工商银行';
            }
            //获取占星师身份信息是否存在，存在则更新
            $astrInfoData = [
                'astr_id' => $this->astrInfo['id'],
                'name' => $param['truename'],
                'telphone' => $this->astrInfo['tel'],
                'id_card' => $param['id_number'],
                'left_pic' => $param['face'],
                'left_pic_info' => '',
                'right_pic' => $param['back'],
                'right_pic_info' => '',
                'hand_idcard_pic' => $param['holding'],
                'hand_idcard_pic_info' => '',
                'bank_card' => $param['bank_num'],
                'bank_name' => $param['bank_name'],
                'bank_id_card' => $param['bank_user_id_number'],
                'bank_id_card_name' => $param['bank_username'],
                'bank_info' => '',
                'bank_branch_info' => '',
                'create_time' => time()
            ];

            $astrData = [
                'avatar' => '',
                'nickname' => ''
            ];

            //识别身份证信息
            //验证身份证正面照片
            $res = $this->checkPicOfIdCard($this->astrInfo['id'], 3, $astrInfoData['left_pic']);
            if ($res['status'] === true)
            {//验证成功
                $month = date('m', $res['data']['birthday']);//19900906
                $day = date('d', $res['data']['birthday']);//19900906
                $sign_index = Util::getSignIndex($month, $day);
                $avatar = '/zhunle_astrologer/avatar/' . $sign_index . '.png';
                $astrData['avatar'] = $avatar;//头像
                $astrData['nickname'] = mb_substr($res['data']['name'], 0, 1) . '老师';//昵称
                $astrInfoData['name'] = $res['data']['name'];//真实姓名
                $astrInfoData['id_card'] = $res['data']['idcard'];//身份证号
                $astrInfoData['left_pic_info'] = json_encode($res['data']);//身份证正面图片信息
            } else
            {
                return show(0, '新增失败，身份证正面照片验证失败！');
            }

            //验证身份证反面照片
            $res = $this->checkPicOfIdCard($this->astrInfo['id'], 4, $astrInfoData['right_pic']);
            if (!$res['status'])
            {
                return show(0, '新增失败，身份证反面照片验证失败！');
            } else
            {
                $astrInfoData['right_pic_info'] = json_encode($res['data']);//身份证反面图片信息
            }

            //验证手持身份证照片
            $res = $this->checkPicOfIdCard($this->astrInfo['id'], 5, $astrInfoData['hand_idcard_pic']);
            if (!$res['status'])
            {
                return show(0, '新增失败，手持身份证照片验证失败！');
            } else
            {
                if ($res['data']['score'] < 0.3)
                {
                    Log::write('新增手持身份证照片认证结果，小于0.3（需要降低点）', 'error', true);
                    return show(0, '新增失败，手持身份证照片认证失败！');
                } else
                {
                    $astrInfoData['hand_idcard_pic_info'] = json_encode($res['data']);//手持身份证正面图片信息
                }
            }

            //验证银行卡信息
            $bankCheckRes = Util::checkBankIdentityThreeElements($astrInfoData['bank_card'], $astrInfoData['bank_id_card'], $astrInfoData['bank_id_card_name']);
            if ($bankCheckRes['status'] === false)
            {
                $data['compeleteState'] = 3;
                $data['compeleteText'] = "<span class='tip'>{$bankCheckRes['msg']}</span>，请修改后重新提交审核。";
                return show(0, $bankCheckRes['msg'] . '，请修改后重新提交审核。');
            } else
            {
                $astrInfoData['bank_info'] = json_encode($bankCheckRes['data']);

                //验证开户行是否正确
                if (strpos($bankCheckRes['data']['bankName'], $astrInfoData['bank_name']) === false && strpos($astrInfoData['bank_name'], $bankCheckRes['data']['bankName']) === false)
                {//不包含 解析出来有可能是 中国工商银行
                    //---------------------------------------------------------------
                    //[ 2024-07-31T14:18:17+08:00 ] 175.167.148.196 POST wechat.goddessxzns.com/astrologer/v2/user/compoleteInfo
                    //[ error ] 请求头：{"model":"taro  RMX3700","channel":"astrologer","version":"1.2.2","access-token":"b995d98a4beba4855222bb94089eeb1b86561185||116444","user-agent":"Dart\/3.2 (dart:io)"}用户新增银行卡资料，支持的银行卡错误（需要更新占星师前端的银行卡列表 或者 去掉银行名字的验证）：用户选择的银行=中国农业银行，查询云市场的支行名字为：农业银行
                    //---------------------------------------------------------------
                    Log::write('用户新增银行卡资料，支持的银行卡错误（需要更新占星师前端的银行卡列表 或者 去掉银行名字的验证）：用户选择的银行=' . $astrInfoData['bank_name'] . '，查询云市场的支行名字为：' . $bankCheckRes['data']['bankName'], 'error', true);
                    return show(0, $bankCheckRes['msg'] . '，开户行错误，请修改后重新提交审核。');
                }

                //根据联行号查询支行信息
                $bank_branch_info = Util::checkBankCode($param['bank_branch_code']);
                if ($bank_branch_info['status'])
                {//成功，检查开户行是否一样
//                    if (strpos($bank_branch_info['data']['bank'], $bank_name) === false)
//                    {//不包含 解析出来有可能是 中国工商银行
//                        Log::write('用户编辑银行卡资料，支持的银行卡错误（需要更新占星师前端的银行卡列表 或者 去掉银行名字的验证）：用户选择的银行=' . $bank_name . '，查询云市场的支行名字为：' . $bank_branch_info['data']['bank'], 'error', true);
//                        return show(0, $bankCheckRes['msg'] . '，开户行错误，请修改后重新提交审核。');
//                    }
                    $astrInfoData['bank_name'] = $bank_branch_info['data']['bank'];
                    $astrInfoData['bank_branch_name'] = $bank_branch_info['data']['lName'];
                    $astrInfoData['bank_branch_info'] = json_encode($bank_branch_info['data']);
                } else
                {//失败
                    Log::write('支行信息查询失败，请修改后重新提交审核。', 'error', true);
                    return show(0, $bankCheckRes['msg'] . '支行信息查询失败，请修改后重新提交审核。');
                }

            }

            //检查数据是否已经添加了
            $astrInfoDataExit = $zlAstrInfoModel->where('astr_id', $this->astrInfo['id'])->find();
            if ($astrInfoDataExit)
            {//存在数据
                //加密数据
                $res1 = $zlAstrInfoModel->UpdeData($this->astrInfo['id'], ['id' => $astrInfoDataExit['id']], Util::astrologerSensitiveInfoDecodeOrEncode($astrInfoData, false));
                if (!$res1)
                {
                    $data['compeleteState'] = 4;
                    $data['compeleteText'] = "<span class='tip'>服务异常，请稍后重试！</span>";
                    Log::write('保存资料失败1,msg=', json_encode($res1), 'error', true);
                    return show(0, '服务异常，请稍后重试！', $data);
                }
            } else
            {
                //添加数据
                $res1 = $zlAstrInfoModel->SaveData($astrInfoData);
                if (!$res1)
                {
                    $data['compeleteState'] = 4;
                    $data['compeleteText'] = "<span class='tip'>服务异常，请稍后重试！</span>";
                    Log::write('保存资料失败1,msg=', json_encode($res1), 'error', true);
                    return show(0, '服务异常，请稍后重试！', $data);
                }
            }
            $res2 = $zlAstrModel->UpdateData($this->astrInfo['id'], ['id' => $this->astrInfo['id']], [
                'nickname' => $astrData['nickname'],
                'avatar' => $astrData['avatar']
            ]);
            if (!$res2)
            {
                $data['compeleteState'] = 4;
                $data['compeleteText'] = "<span class='tip'>服务异常，请稍后重试！</span>";
                Log::write('保存资料失败2,msg=', 'error', true);
                return show(0, '服务异常，请稍后重试！', $data);
            }
            $data['compeleteState'] = 5;
            $data['compeleteText'] = "提交成功";
            $data['userinfo'] = null;
            return show(200, '提交成功', $data);
        } else
        {
            if ($astrInfo)
            {
                $data['userinfo'] = [
                    'avatar' => $this->astrInfo['avatar'],
                    'nickname' => $this->astrInfo['nickname'],
                    'truename' => $astrInfo['name'],
                    'id_number' => $astrInfo['id_card'],
                    'face' => $astrInfo['left_pic'],
                    'back' => $astrInfo['right_pic'],
                    'holding' => $astrInfo['hand_idcard_pic'],
                    'bank_num' => $astrInfo['bank_card'],
                    'bank_name' => $astrInfo['bank_name'],
                    'bank_address' => $astrInfo['bank_branch_name'],
                    'bank_username' => $astrInfo['name'],
                    'bank_user_id_number' => $astrInfo['id_card'],
                    'bank_verfiy' => '',
                    'tel' => $this->astrInfo['tel'],
                ];
                if ($this->astrInfo['check_status'] == 22)
                {
                    //获取审核信息
                    $check = (new ZlcrContentCheck())->getContentCheckInfo($this->astrInfo['id'], 4, ['status', 'ali_ckeck', 'desc']);
                    $msg = $check['desc'] ?: $check['ali_ckeck'];
//                    $msg = '123';
                    $data['compeleteState'] = 4;
                    //获取私有图片地址
                    $data['userinfo']['face_private_url'] = Upload::getOssPrivateUrl($data['userinfo']['face']);
                    $data['userinfo']['back_private_url'] = Upload::getOssPrivateUrl($data['userinfo']['back']);
                    $data['userinfo']['holding_private_url'] = Upload::getOssPrivateUrl($data['userinfo']['holding']);
                    $data['compeleteText'] = $msg;
                    return show(200, $msg, $data);
                } elseif ($this->astrInfo['check_status'] == 21)
                {
                    $data['compeleteState'] = 3;
                    $data['compeleteText'] = "请等待客服审核，留意短信通知，1-3个工作日内完成审核。";
                    $data['userinfo'] = null;
                    return show(200, '请求成功', $data);
                } elseif ($this->astrInfo['check_status'] == 30)
                {
                    $data['compeleteState'] = 5;
                    $data['compeleteText'] = '恭喜您成功完善了相关资料';
                    $data['userinfo'] = null;
                    return show(200, '请求成功', $data);
                } else
                {
                    $data['compeleteState'] = 1;
//                    $data['compeleteState'] = 2; //test
                    $data['compeleteText'] = '请完善相关资料';
                    return show(200, '请求成功', $data);
                }
            } else
            {//没有信息，刚开始上传，只把手机号给用户返回
                $data['userinfo'] = [
                    'tel' => $this->astrInfo['tel'],
                ];
                $data['compeleteState'] = 1;
//                $data['compeleteState'] = 2;//test
                return show(200, '请求成功', $data);
            }
            return show(0, $msg ?? '', $data);
        }
    }

    /**
     * 验证用户完善资料请求参数
     * @param $param
     * @param $zlAstrModel
     * @return array
     */
    private function checkCompoleteInfoParam($param, $zlAstrModel)
    {
        $data['userinfo'] = $param;

        if (!isset($param['truename']) || !$param['truename'])
        {
            return [
                'status' => false,
                'msg' => '请输入真实姓名',
                'data' => []
            ];
        }

        if (!isset($param['id_number']) || !$param['id_number'])
        {
            return [
                'status' => false,
                'msg' => '请输入身份证号',
                'data' => []
            ];
        }

        if (!isset($param['face']) || !$param['face'])
        {
            return [
                'status' => false,
                'msg' => '请上传身份证正面照片',
                'data' => []
            ];
        }

        if (!isset($param['back']) || !$param['back'])
        {
            return [
                'status' => false,
                'msg' => '请上传身份证反面照片',
                'data' => []
            ];
        }

        if (!isset($param['holding']) || !$param['holding'])
        {
            return [
                'status' => false,
                'msg' => '请上传手持身份证照片',
                'data' => []
            ];
        }

        if (!isset($param['bank_num']) || !$param['bank_num'])
        {
            return [
                'status' => false,
                'msg' => '请输入银行卡号',
                'data' => []
            ];
        }

        if (!isset($param['bank_name']) || !$param['bank_name'])
        {
            return [
                'status' => false,
                'msg' => '请输入开户行',
                'data' => []
            ];
        }

        if (!isset($param['bank_username']) || !$param['bank_username'])
        {
            return [
                'status' => false,
                'msg' => '请输入收款人姓名',
                'data' => []
            ];
        }

        if (!isset($param['bank_user_id_number']) || !$param['bank_user_id_number'])
        {
            return [
                'status' => false,
                'msg' => '请输入收款人身份证号',
                'data' => []
            ];
        }

        if (!isset($param['bank_verfiy']) || !$param['bank_verfiy'])
        {
            return [
                'status' => false,
                'msg' => '请输入验证码',
                'data' => []
            ];
        }

        //验证手机验证码
        $code = Cache::get($this->astrInfo['tel']);
        if ($code != $param['bank_verfiy'])
        {
            $data['compeleteState'] = 4;
            $data['compeleteText'] = '您填写的 <span class="tip">验证码错误</span> 错误，请修改后重新提交审核。';
            return [
                'status' => false,
                'msg' => '验证码错误',
                'data' => $data
            ];
        }
    }

    /**
     * 检查图片是否解析完成
     * @param int $astrId
     * @param int $type 3：身份证正面；4：身份证反面；5：手持身份证；
     * @param string $img_url 图片的oss地址
     * @return array|false[]
     */
    private function checkPicOfIdCard(int $astrId, int $type = 3, string $img_url = '')
    {
        $data = [
            'status' => false,
            'data' => ''
        ];

        $key = [
            3 => 'left_pic',
            4 => 'right_pic',
            5 => 'hand_idcard_pic',
        ];

        $uploadPath = Cache::get('astr_admin:upload_path:' . $astrId, []);

        if (isset($uploadPath[$key[$type]]['path'], $uploadPath[$key[$type]]['data']) && $img_url === $uploadPath[$key[$type]]['path'])
        {
            return [
                'status' => true,
                'data' => $uploadPath[$key[$type]]['data']
            ];
        } else
        {
            return $data;
        }
    }
}
